# coding=utf-8
# author = jamon
_need_reload = True
from typing import Optional, List

import pygame
from obespoir.share.singleton import Singleton
from pygame.event import Event
from pygame.surface import Surface
import sys
import traceback

from client.application import Application
from client.model.entity.brick import Brick
from client.model.entity.home import Home
from client.model.entity.ice import Ice
from client.model.entity.iron import Iron
from client.model.entity.river import River
from client.model.entity.tree import Tree
from client.model.entity_manager import entity_mgr
from client.model.gate_data import GateData
from obespoir.share.espoir_log import global_log as logger
from package.posi import Position
from package.static.const import TypeIdConst, Faction

if __name__ == "__main__":
    import os

    sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))

from client.config import ClientConfig


def __on_after_reload__():
    GateEditor().on_reload()


class GateEditor(object, metaclass=Singleton):
    KEY_TO_PLAYER = {
        pygame.K_UP: 1,
        pygame.K_DOWN: 1,
        pygame.K_LEFT: 1,
        pygame.K_RIGHT: 1,
    }

    def __init__(self):
        super(GateEditor, self).__init__()
        self.config = ClientConfig()
        self.background_img: Surface = pygame.image.load(self.config.background_image_path)
        # 当局游戏数据
        self.gate_data: Optional[GateData] = None
        self._screen: Optional[Surface] = None
        self.need_reload: bool = False

    @property
    def screen_entities(self):
        return entity_mgr.screen_entities

    def init_screen(self, gate_id: int):
        self.need_reload = False
        self.gate_data = GateData()
        self.gate_data.init_gate(gate_id)
        width = self.gate_data.GRID_SIZE * self.gate_data.config.width
        height = self.gate_data.GRID_SIZE * self.gate_data.config.height
        screen = pygame.display.set_mode((width, height))
        self._screen = screen
        self._parse_gate_map()

    def show(self, gate_id: int = 1):
        """
        :param gate_id: int
        :return:
        """
        self.init_screen(gate_id=gate_id)

    async def update(self, events: List[Event] = None):
        # 背景填充
        self._screen.fill((0, 0, 0))
        self._screen.blit(self.background_img, (0, 0))

        # 玩家事件捕捉
        self.handle_player_event(events)

        # 地图显示
        self._show_map()

    def on_reload(self):
        # 清空原来的元素
        for _, group in self.screen_entities.items():
            if len(group):
                group.empty()

        self.show(gate_id=self.gate_data.gate_id)

    def handle_player_event(self, events: List[Event] = None):
        for event in events:
            if pygame.QUIT == event.type:
                pygame.quit()
                sys.exit()

        # 按压事件
        press_event = pygame.key.get_pressed()
        if press_event[pygame.K_F5]:
            # 刷新
            self.need_reload = True
            return

    def _show_map(self):
        for _id, group in self.screen_entities.items():
            if len(group):
                group.draw(self._screen)

    def _parse_gate_map(self):
        path = os.path.join(ClientConfig().root_dir, self.gate_data.config.path)
        f = open(path, errors="ignore")
        row_no = 0
        max_col_no = 1
        for line in f.readlines():
            line = line.strip('\n')
            for col_no, elem in enumerate(line.split(" ")):
                position = Position(col_no * self.gate_data.GRID_SIZE, row_no * self.gate_data.GRID_SIZE)
                max_col_no = max(col_no, max_col_no)
                if "B" == elem:
                    obj = Brick(TypeIdConst.ENTITY_BRICK_WALL, faction=Faction.NONE, position=position)
                    self.screen_entities[TypeIdConst.ENTITY_BRICK_WALL].add(obj)
                elif "C" == elem:
                    obj = Ice(TypeIdConst.ENTITY_ICE, faction=Faction.NONE, position=position)
                    self.screen_entities[TypeIdConst.ENTITY_ICE].add(obj)
                elif "H" == elem:
                    obj = Home(TypeIdConst.ENTITY_HOME, faction=Faction.OUR_FACTION, position=position)
                    self.screen_entities[TypeIdConst.ENTITY_HOME].add(obj)
                elif "E" == elem:
                    obj = Home(TypeIdConst.ENTITY_HOME, faction=Faction.ENEMY_FACTION, position=position)
                    self.screen_entities[TypeIdConst.ENTITY_HOME].add(obj)
                elif "I" == elem:
                    obj = Iron(TypeIdConst.ENTITY_IRON_WALL, faction=Faction.NONE, position=position)
                    self.screen_entities[TypeIdConst.ENTITY_IRON_WALL].add(obj)
                elif "R" == elem:
                    obj = River(TypeIdConst.ENTITY_RIVER, faction=Faction.NONE, position=position)
                    self.screen_entities[TypeIdConst.ENTITY_RIVER].add(obj)
                elif "T" == elem:
                    obj = Tree(TypeIdConst.ENTITY_TREE, faction=Faction.NONE, position=position)
                    self.screen_entities[TypeIdConst.ENTITY_TREE].add(obj)
            row_no += 1


def main():
    logger.init_log_config("estank", log_dir="./logs")
    pygame.display.set_caption("坦克大战地图预览")
    app = Application()
    app.start()
    editor = GateEditor()
    gate_id = int(sys.argv[1])
    editor.show(gate_id)
    app.add_scene_event("editor", editor.update)
    app.run()


if __name__ == "__main__":
    try:
        main()
    except Exception:  # noqa
        print(traceback.format_exc())
    finally:
        import os

        os.system("pause")
